package gr.atc.epart;

import gr.atc.epart.actions.Petition;
import gr.atc.epart.actions.Action.Type;
import gr.atc.epart.net.ActionsPage.SortBy;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

import org.json.JSONException;
import org.json.JSONObject;

import android.net.Uri;

public class BackEndServicesProvider
{

	private class BackEndServicesURLProvider
	{
		public String getLoginURL()
		{
			return String.format("http://%s/epart/%s", EPartSettings.getInstance().getBackEndURL(),"login.php");
		}

		public String getRetrievePetitionURL()
		{
			return String.format("http://%s/%s", EPartSettings.getInstance().getBackEndURL(),"petition.php");
		}

		public String getRetrieveActionsURL()
		{
			return String.format("http://%s/%s", EPartSettings.getInstance().getBackEndURL(),"actions.php");
		}

		public String getAddActionURL()
		{
			return String.format("http://%s/%s", EPartSettings.getInstance().getBackEndURL(),"createaction.php");
		}

		public String getVoteForPetitionURL()
		{
			return String.format("http://%s/%s", EPartSettings.getInstance().getBackEndURL(),"signpetition.php");
		}

		public String getSubmitCommentOnActionURL()
		{
			return String.format("http://%s/%s", EPartSettings.getInstance().getBackEndURL(),"comment.php");
		}

		public String getCommentForActionURL()
		{
			return String.format("http://%s/%s", EPartSettings.getInstance().getBackEndURL(),"comments.php");		
		}

	}

	private BackEndServicesURLProvider _urlProvider;

	public BackEndServicesProvider()
	{
		_urlProvider = new BackEndServicesURLProvider();	
	}

	//
	// Login/Logout
	//
	public String logIn(String username, String password)
	{
		HttpConnector connection= new HttpConnector();

		String loginRequest  = createLoginRequest(username, password);
		String loginResponse = connection.executeGetRequest(loginRequest);

		return loginResponse;
	}

	private String createLoginRequest(String username, String password)
	{
		//TODO:: complete the request with the real login url  
		return String.format("%s?u=%s&p=%s",_urlProvider.getLoginURL(),username,password );
	}

	public void logOut(String authToken)
	{
		// disconnect the user with that token
	}

	//
	// Get stored Google credentials for user
	//



	//
	//
	//
	//
	public JSONObject getPetition(int id, String userName)
	{

		try
		{
			HttpConnector connection= new HttpConnector();

			String getPetitionRequest  = createGetPetitionRequest(id,userName);
			String getPetitionResponse = connection.executeGetRequest(getPetitionRequest);

			return new JSONObject(getPetitionResponse);
		} 
		catch (JSONException e)
		{
			try 
			{
				return new JSONObject("{\"success\":false,reason:\"Unknown\"}");
			}
			catch (JSONException ee)
			{
				return null;
			}
		}
	}

	private String createGetPetitionRequest(int id, String userName)
	{
		if (userName==null)
		{
			return String.format("%s?id=%d",_urlProvider.getRetrievePetitionURL(),id);
		}
		else
		{
			return String.format("%s?id=%d&user=%s",_urlProvider.getRetrievePetitionURL(),id,userName);
		}
	}

	public JSONObject createPetition(Petition petition)
	{

		return createAction(Type.ePetition, petition.getName(), petition.getDescription(), petition.getCreator().getName(),
				petition.getStartDate(), petition.getStopDate(), petition.getTags(), petition.isLogInRequired(),0);
	}

	public JSONObject voteForPetition(int petitionId, String userName,String comment)
	{
		try
		{
			HttpConnector connection= new HttpConnector();

			String getVoteForPetitionRequest  = createGetVoteForPetitionRequest(petitionId,userName,comment);
			String getVoteForPetitionResponse = connection.executeGetRequest(getVoteForPetitionRequest);

			return new JSONObject(getVoteForPetitionResponse);
		} 
		catch (JSONException e)
		{
			try 
			{
				return new JSONObject("{\"success\":false,reason:\"Unknown\"}");
			}
			catch (JSONException ee)
			{
				return null;
			}
		}
	}

	private String createGetVoteForPetitionRequest(int petitionId, String userName,String comment)
	{
		return String.format("%s?id=%d&user=%s&comment=%s",_urlProvider.getVoteForPetitionURL(),petitionId,userName,Uri.encode(comment));
	}

	public JSONObject getAction(Type actionType, String searchText,String creator,
			Date startDate, Date stopDate, String [] tags, SortBy sortBy,int pageNumber,int pageSize)
	{
		try
		{

			HttpConnector connection= new HttpConnector();

			String getActionsRequest  = createGetActionsRequest(actionType, searchText,creator,startDate, stopDate, tags, sortBy,pageNumber,pageSize);
			String getActionsResponse = connection.executeGetRequest(getActionsRequest);

			return new JSONObject(getActionsResponse);
		} 
		catch (Exception e)
		{
			try 
			{
				return new JSONObject("{\"success\":false,reason:\"Unknown\"}");
			}
			catch (Exception ee)
			{
				return null;
			}
		}

	}

	private String concatenateTags(String[] tags)
	{
		// concatenate tags
		if (tags != null)
		{
			StringBuilder sb =new StringBuilder();
			for (int i=0; i<tags.length; i++) 
			{
				// do not use %20 because the tags become a single word
				// use simple space instead
				if (i!=0) 
					sb.append(" ");

				sb.append(tags[i]);
			}
			return sb.toString();
		}
		else
		{
			return "";
		}
	}

	private String getActionType(Type actionType)
	{
		switch (actionType)
		{
			case Deliberation:
				return "deliberation";

			case ePetition:
				return "petition";

			case Survey:
				return "survey";

			case Event:
				return "event";
			case All:	
			default:
				return "all";
		}
	}

	private String getDateString(Date  date)
	{
		if (date ==null)
			return "";

		SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy"); 
		return formatter.format(date);
	}

	private String getSortBy(SortBy sortBy)
	{
		switch (sortBy)
		{
			case Date:
				return "date";
			case Name:
				return "name";
			case Popularity:
				return "popularity";
			default:
				return "";
		}

	}

	private String createGetActionsRequest(Type actionType, String searchText,String creator,
			Date startDate, Date stopDate, String [] tags, SortBy sortBy,int pageNumber,int pageSize)
	{

		return String.format("%s?type=%s&text=%s&creator=%s&tags=%s&from=%s&to=%s&page=%d&pageSize=%d&sortBy=%s",
				_urlProvider.getRetrieveActionsURL(),
				getActionType(actionType),
				(searchText==null)?"":searchText,
				creator,
				Uri.encode(concatenateTags(tags)).toString(),
				getDateString(startDate),
				getDateString(stopDate),
				pageNumber,
				pageSize,
				getSortBy(sortBy)
		);


	}

	public JSONObject createAction(Type actionType, String name,
			String description, String creator, Date startDate, Date stopDate,
			String[] tags, boolean isLoginRequired, int seriesId)
	{
		try
		{
			HttpConnector connection= new HttpConnector();


			// the parameters to a POST request are created as a map of KEYS<=>VALUES
			HashMap<String, String> parameters = new HashMap<String, String>();
			parameters.put("type",getActionType(actionType)); 
			parameters.put("name",name);
			parameters.put("description",description);

			if (tags != null)
				parameters.put("tags",concatenateTags(tags));

			parameters.put("creator",creator);

			SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy"); 

			if (startDate!=null)
				parameters.put("start",formatter.format(startDate));

			if (stopDate!=null)
				parameters.put("stop", formatter.format(stopDate));

			parameters.put("loginRequired",Boolean.toString(isLoginRequired));
			
			if (seriesId !=0)
				parameters.put("seriesid",Integer.toString(seriesId));

			String createActionsResponse = connection.executePostRequest(_urlProvider.getAddActionURL(),parameters);

			return new JSONObject(createActionsResponse);

		} 
		catch (Exception e)
		{
			try 
			{
				return new JSONObject("{\"success\":false,reason:\"Unknown\"}");
			}
			catch (Exception ee)
			{
				return null;
			}
		}
	}

	public JSONObject commentOnAction(int actionId, String userName,String comment)
	{
		try
		{
			HttpConnector connection= new HttpConnector();

			// the parameters to a POST request are created as a map of KEYS<=>VALUES
			HashMap<String, String> parameters = new HashMap<String, String>();
			parameters.put("actionId",Integer.toString(actionId)); 
			parameters.put("user",userName);
			parameters.put("comment",comment);

			String commentOnActionResponse = connection.executePostRequest(_urlProvider.getSubmitCommentOnActionURL(),parameters);

			return new JSONObject(commentOnActionResponse);

		} 
		catch (Exception e)
		{
			try 
			{
				return new JSONObject("{\"success\":false,reason:\"Unknown\"}");
			}
			catch (Exception ee)
			{
				return null;
			}
		}

	}

	
	public JSONObject getComments(int actionId, int pageNumber, int pageSize)
	{
		try
		{

			HttpConnector connection= new HttpConnector();

			String getActionsCommentsRequest  = createGetActionCommentsRequest(actionId,pageNumber,pageSize);
			String getActionsCommentsResponse = connection.executeGetRequest(getActionsCommentsRequest);
				
			return new JSONObject(getActionsCommentsResponse);
		} 
		catch (Exception e)
		{
			try 
			{
				return new JSONObject("{\"success\":false,reason:\"Unknown\"}");
			}
			catch (Exception ee)
			{
				return null;
			}
		}
	}

	private String createGetActionCommentsRequest(int actionId, int pageNumber,int pageSize)
	{
		
		return String.format("%s?actionId=%d&page=%d&pageSize=%d",_urlProvider.getCommentForActionURL(),actionId,pageNumber,pageSize);
	}
	
	
}
